/**
* @author Matias Menafra
* @createdDate 03/08/2010
*/
public with sharing class Contactsextension{

    //private final Integer MAX_SIZE          = 131072; // 128Kb
    private final Integer MAX_SIZE          = 512000; // 500Kb
    private final Integer MAX_LENGTH_NAME   = 71;
    private final String  ERROR_NO_SAVE     = 'Please select a file to upload and try again.';
    //private final String  ERROR_IMG_TYPE    = 'The image must be .jpg, .gif or .png';   
    private final String  ERROR_IMG_TYPE    = 'The image must be .jpg or .png';   
    private final String  ERROR_IMG_SIZE    = 'The image maximum size is 500 Kb.';
    private final String  ERROR_PRINT_ID_CARD    = 'This ID card was printed before.';

    
    //private Set<String> imagesTypes         = new Set<String> {'image/jpeg', 'image/pjpeg', 'image/png', 'image/x-png', 'image/gif'};
    private Set<String> imagesTypes         = new Set<String> {'image/jpeg', 'image/pjpeg', 'image/png', 'image/x-png'};
    private Set<String> notAllowedTypes     = new Set<String> {'application/octet-stream'};
    
    public Attachment   newAttach           { set; get; }
    public Attachment   file                { set; get; }
    private String      parentId            { set; get; }
    public String       postAction          { set; get; }
    public String       error               { set; get; }
    public Boolean      hasPicture          { set; get; }
    
    /**
    * Constructor
    */ 
    public Contactsextension( ApexPages.StandardController stdController ){
        
        this.parentId       = stdController.getId();
        this.hasPicture     = false;
        this.newAttach      = new Attachment();
        this.error          = '';
        
        //List<Attachment> attList = [ Select ParentId, Name, Id, ContentType, BodyLength From Attachment where ParentId =: this.parentId and name = 'Contact Picture' limit 1];
        List<Attachment> attList = [ Select ParentId, Name, Id, ContentType, BodyLength From Attachment where ParentId =: this.parentId and name like 'Contact Picture%' order by name desc limit 1 ];
        if( attList.size() > 0 ){
            this.file               = attList.get( 0 );
            this.hasPicture         = true;
        }
    }
    
    /**
    * Upload action, store the file or replace if exists
    * @return thePage
    */
    public PageReference uploadAction(){
        
        PageReference thePage = new PageReference( '/'+ parentId );
        thePage.setRedirect( true );
        if( this.validate() ){
            return ( this.saveCurrentPicture() ) ? thePage : null;
        }
        else{
            this.newAttach = new Attachment();
            return null;
        }
    }
    
    
    /**
    * Save the New Attachment as Contact Picture
    * @return : boolean
    */
    public Boolean saveCurrentPicture(){
        Savepoint sp = Database.setSavepoint();
        try{
            //delete [ Select Id From Attachment where ParentId =: this.parentId and name = 'Contact Picture' limit 1 ];
            this.newAttach.parentId = this.parentId;
            //this.newAttach.name = 'Contact Picture';
            DateTime datetimeNow = datetime.now();
            this.newAttach.name = 'Contact Picture' + datetimeNow.getTime();
            insert this.newAttach;
            
            //Update ID-Card Print Counter to 0
            //Contact contactObj = [ Select Id, Name, ID_Card_Print_Counter__c From Contact where Id =: this.parentId];
            //contactObj.ID_Card_Print_Counter__c = 0;
            //update contactObj;
        
            return true;
        } 
        catch( Exception e ){
            this.error += ERROR_NO_SAVE+'<br/>';
            Database.rollback( sp );
            return false;
        }
    }
    
    
    /**
    * Detele action, delete the curren image
    * @return thePage
    */
    public PageReference deleteAction(){
        
        PageReference thePage = new PageReference( '/'+ parentId );
        thePage.setRedirect( true );
        delete this.file;
        return thePage;
    }
    
    /**
    * Run all verification for the file to upload
    * @return ret
    */
    private Boolean validate(){
        Boolean ret = true;
        this.error = '';
        if( !imagesTypes.contains( newAttach.ContentType ) ){
            this.error += ERROR_IMG_TYPE+'<br/>';
            ret = false;
        }
        // Validate Image Size
        else if(newAttach.BodyLength > MAX_SIZE) {
            this.error += ERROR_IMG_SIZE + '<br/>';
            ret = false;
        }
        return ret;
    }
    
    /**
    * Cancel action
    * @return thePage a page reference
    */
    public PageReference cancel(){
        PageReference thePage = new PageReference( '/'+ parentId );
        thePage.setRedirect( true );
        return thePage;
    }
    
       /**
    * Print action
    * @return thePage a page reference
    */
    public PageReference print(){
        Savepoint sp = Database.setSavepoint();
        // Update ID-Card Print Counter to 1
        try{
            //Contact contactObj = [ Select Id, Name, ID_Card_Print_Counter__c From Contact where Id =: this.parentId];
        
            //if(contactObj.ID_Card_Print_Counter__c <> 0) {
            //    this.error += ERROR_PRINT_ID_CARD + '<br/>';
            //    return null;
            //}
            //contactObj.ID_Card_Print_Counter__c = 1;
            
            return null;     
        }
        catch (Exception e) {
            this.error += ERROR_NO_SAVE+'<br/>';
            Database.rollback( sp );
            return null;
        }
        
        //Cancel Action
        PageReference thePage = new PageReference( '/apex/vfp_Print_ID_Card?id=' + parentId );
        thePage.setRedirect( true );
        return thePage;
    }
    /**
    * Test cases for rigth image types and a wrong type
    */
    public static testMethod void testImageTypes(){
        TestUtilities tu = TestUtilities.generateTest();
        
        ApexPages.StandardController sc;
        Contactsextension cTest;
        
        Contact myContact = tu.aContac;
    
        //List<String> types = new List<String>{'image/jpeg', 'image/pjpeg', 'image/png', 'image/x-png', 'image/gif'};
        List<String> types = new List<String>{'image/jpeg', 'image/pjpeg', 'image/png', 'image/x-png'};
    
        Attachment tempAtt = new Attachment();
        
        Test.startTest();
            for( String aType: types ){
                sc = new ApexPages.StandardController(myContact);
                cTest = new Contactsextension( sc );
                cTest.newAttach.Name = 'Picture-' + sc.getId();
                cTest.newAttach.Body = Blob.valueOf('String');
                cTest.newAttach.ContentType = aType;
                cTest.uploadAction();
                
                cTest.newAttach.Body = Blob.valueOf('String');
                
                //System.assert( cTest.newAttach.name == 'Contact Picture', 'Name not equals' );
                System.assert( cTest.newAttach.ContentType == aType, 'Types not equals' );
                        
            }

            sc = new ApexPages.StandardController(myContact);
            cTest = new Contactsextension( sc );
            cTest.newAttach.Name = 'Picture-' + sc.getId();
            cTest.newAttach.Body = Blob.valueOf('String');
            cTest.newAttach.ContentType = 'image/YYY';
            cTest.uploadAction();
            //System.assert( cTest.error == 'The image must be .jpg, .gif or .png<br/>', 'Error in error message.' + cTest.error);
            System.assert( cTest.error == 'The image must be .jpg or .png<br/>', 'Error in error message.' + cTest.error);

            cTest = new Contactsextension( sc );
            cTest.uploadAction();
            
        Test.stopTest();
    } 
    
    /**
    *Test upload picture with no picture at the start.
    *
    */
    public static testMethod void testNoPicture(){
        TestUtilities tu = TestUtilities.generateTest();
        
        Test.startTest();
        ApexPages.StandardController sc = new ApexPages.StandardController( tu.aContac );
        Contactsextension cTest = new Contactsextension( sc );
        cTest.newAttach.Name = 'Picture-' + sc.getId();
        cTest.newAttach.Body = Blob.valueOf('String');
        cTest.newAttach.ContentType = 'image/jpeg';
        cTest.uploadAction();

        Attachment attUploaded = [ SELECT name, parentId, body, ContentType FROM Attachment WHERE parentId =: sc.getId() AND name like 'Contact Picture%'];
        System.assert( attUploaded != null, 'No attachment uploaded.' );
        //System.assert( attUploaded.name == 'Contact Picture', 'Name not equals.' );
        System.assert( attUploaded.Body.toString() == Blob.valueOf('String').toString(), 'Bodys not equals.' );
        System.assert( attUploaded.ContentType == 'image/jpeg', 'Types not equals.' );

        
        // Replace string
        sc = new ApexPages.StandardController( tu.aContac );
        cTest = new Contactsextension( sc );
        cTest.newAttach.Name = 'Picture-' + sc.getId();
        cTest.newAttach.Body = Blob.valueOf('Other String For Replacement');
        cTest.newAttach.ContentType = 'image/png';
        cTest.uploadAction();
        
        attUploaded = [ SELECT name, parentId, body, ContentType FROM Attachment WHERE parentId =: sc.getId() AND name like 'Contact Picture%' limit 1 ];
        System.assert( attUploaded != null, 'No attachment uploaded.' );
        //System.assert( attUploaded.name == 'Contact Picture', 'Name not equals.' );
        //System.assert( attUploaded.Body.toString() == Blob.valueOf('Other String For Replacement').toString(), 'Bodys not equals.' );
        //System.assert( attUploaded.ContentType == 'image/png', 'Types not equals.' );
        
        
        Id stroringAttIdForRetreve = cTest.newAttach.id;
        cTest = new Contactsextension( sc );
        cTest.deleteAction();
        List<Attachment> attUploadedList = [ SELECT id FROM Attachment WHERE id =: stroringAttIdForRetreve ];

        //System.assert( attUploadedList.size() == 0, 'Attachment not deleted !!!' );
        
        Test.stopTest();    
    }
}